package org.example.service.impl;

import jakarta.servlet.http.HttpServletRequest;
import org.example.config.UserContextConfig;
import org.example.dao.CommentDOMapper;
import org.example.dataobject.CommentDO;
import org.example.error.BusinessException;
import org.example.error.EmBusinessError;
import org.example.service.CommentService;
import org.example.service.model.CommentModel;
import org.example.service.model.UserModel;
import org.example.validator.ValidationResult;
import org.example.validator.Validatorimpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author xietl
 * @date 2025/9/1  15:56
 * @description 评论实现类
 */
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentDOMapper commentDOMapper;
    @Autowired
    private Validatorimpl validator;
    @Autowired
    private RedisTemplate<String,Object> jsonRedisTemplate;

    private static final String COMMENT_CACHE_PREFIX = "comment_list:";
    private static final long CACHE_EXPIRE_TIME = 10; // 缓存过期时间（分钟）
    private static final long DELAY_DELETE_TIME = 500; // 延时删除时间（毫秒）


    /**
     *
     * 添加评论
     * @param postId 帖子ID
     * @param commentContent 评论内容
     * @param request HTTP请求（用于获取用户信息）
     * @return
     * @throws BusinessException
     */

    private int addComment(int postId, String commentContent, HttpServletRequest request) throws BusinessException {
        UserModel userModel = UserContextConfig.getUserModel();
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, EmBusinessError.USER_NOT_LOGIN.getErrMsg());
        }
       CommentModel comment = new CommentModel();
        comment.setInvitationId(postId);
        comment.setCommentContent(commentContent);
        comment.setUserId(userModel.getId());
        comment.setCreateTime(new Date());
        comment.setStatus(1);
        comment.setVersion(0);
       ValidationResult validationResult = validator.validate(comment);
        if(validationResult.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,validationResult.getErrMsg());
        }
        CommentDO commentDO=new CommentDO();
        BeanUtils.copyProperties(comment,commentDO);
        commentDOMapper.insertSelective(commentDO);
        return commentDO.getId();
    }

    @Override
    @Transactional
    public CommentDO addCommentAndReturn(int postId, String commentContent, HttpServletRequest request) throws BusinessException {
        deleteCommentCache(postId);

        int commentId = addComment(postId, commentContent, request);
        CommentDO commentDO = commentDOMapper.selectByPrimaryKey(commentId);
        if (commentDO == null) {
            throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "评论数据异常");
        }
        //延迟双删：异步删除缓存
        asyncDelayDeleteCache(postId);
        return commentDO;
    }



    @Override
    @Transactional
    public List<CommentDO> getCommentsByPostId(int postId) throws BusinessException {
        String cacheKey = COMMENT_CACHE_PREFIX + postId;
        // 从缓存中获取评论列表
        List<CommentDO> cacheComents=(List<CommentDO>) jsonRedisTemplate.opsForValue().get(cacheKey);
        if(cacheComents!=null){
            return cacheComents;
        }
        List<CommentDO> commentDOList = commentDOMapper.selectByPostIdOrderByTimeDesc(postId);
        //保存到缓存
        jsonRedisTemplate.opsForValue().set(cacheKey,commentDOList,CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
        return commentDOList;
    }

    @Override
    public int deleteComment(int commentId, HttpServletRequest request) throws BusinessException {
        UserModel userModel = UserContextConfig.getUserModel();
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, EmBusinessError.USER_NOT_LOGIN.getErrMsg());
        }
        CommentDO commentDO = commentDOMapper.selectByPrimaryKey(commentId);
        if (commentDO == null) {
            throw new BusinessException(EmBusinessError.COMMENT_NOT_EXIST, EmBusinessError.COMMENT_NOT_EXIST.getErrMsg());
        }

        // 获取帖子ID用于缓存操作
        int postId = commentDO.getInvitationId();

        // 1. 第一次删除缓存
        deleteCommentCache(postId);

        int result = commentDOMapper.softDeleteComment(commentId,userModel.getId());

        // 2. 延时双删：异步延时删除缓存
        asyncDelayDeleteCache(postId);

        return result;
    }

    @Override
    public int countCommentsByPostId(int postId) throws BusinessException {
        return 0;
    }

    @Override
    public void invalidateCommentCache(int postId) {
        deleteCommentCache(postId);
    }

    /**
     * 删除评论缓存
     * @param postId 帖子ID
     */
    private void deleteCommentCache(int postId) {
        String cacheKey = COMMENT_CACHE_PREFIX + postId;
        jsonRedisTemplate.delete(cacheKey);
    }
    /**
     * 异步延时删除缓存
     * @param postId 帖子ID
     */
    @Async("asyncExecutor")
    public CompletableFuture<Void> asyncDelayDeleteCache(int postId) {
        try {
            // 延时一段时间后再删除缓存
            Thread.sleep(DELAY_DELETE_TIME);
            deleteCommentCache(postId);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return CompletableFuture.completedFuture(null);
    }


}